package com.api.generation.controller;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.api.generation.constants.ApiGenConstants;
import com.api.generation.domain.ApiGenAccess;
import com.api.generation.domain.ApiGenExecute;
import com.api.generation.domain.ApiGenInfo;
import com.api.generation.service.IApiGenAccessService;
import com.api.generation.service.IApiGenExecuteService;
import com.api.generation.service.IApiGenInfoService;
import com.api.generation.service.IApiGenService;
import com.api.generation.util.ApiGenCacheUtils;
import com.ruoyi.common.core.web.controller.BaseController;
import com.ruoyi.common.core.web.domain.AjaxResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Locale;


@RestController
@RequestMapping("/execute/api")
@Api(tags = "数据服务通用接口")
@Log4j2
public class ApIGenController extends BaseController {


    @Autowired
    private IApiGenService iApiGenService;

    @Autowired
    private IApiGenExecuteService apiGenExecuteService;

    @Autowired
    private IApiGenAccessService apiGenAccessService;

    @Autowired
    private IApiGenInfoService iApiGenInfoService;

    @PostMapping()
    @ApiOperation(value = "通用接口获取数据", notes = "通用接口获取数据")
    public AjaxResult apIGenMethod(HttpServletRequest request, HttpServletResponse response) {
        // 1.从rides缓存中判断除了固定的api,path路径是否存在
        String servletPath = (String) request.getAttribute("servletPath");
        log.info("请求路径:{}",servletPath);
        ApiGenInfo apiGenInfoCache = iApiGenService.getApiGenInfoCache(servletPath);
        if(null==apiGenInfoCache){
            ApiGenInfo apiGenInfo = iApiGenInfoService.selectApiGenInfoByApiPath(servletPath);
            if(null==apiGenInfo){
                return notfound("请求api不存在");
            }else{
                ApiGenCacheUtils.setApiGenInfoCache(apiGenInfo.getApiPath(),apiGenInfo);
            }
        }
        String status = apiGenInfoCache.getStatus();
        String apiPublish = apiGenInfoCache.getApiPublish();
        if(ApiGenConstants.DEACTIVATE_STATUS.equals(status)){
            return error("请求api已停用");
        }
        if(ApiGenConstants.NOT_PUBLISH_STATUS.equals(apiPublish)){
            return error("请求api未发布");
        }
        // 2.入参校验: 根据api_id获取缓存中请求api的出入参json格式，与当前请求的入参做校验
        // 2.1   HttpServletRequest 中获取请求体（Body）中的参数
        JSONObject parameterFromBody=null;
        try {
             parameterFromBody = getParameterFromBody(request);
        } catch (Exception e) {
            e.printStackTrace();
            return warn("获取请求body入参异常信息:"+e.getMessage());
        }

        // 2.2 根据api_id,获取请求入参
        Long apiId = apiGenInfoCache.getId();

        // 2.3 根据api_id,获取操作类型 CREATE、UPDATE、SELECT、EXPORT
        ApiGenExecute apiGenExecuteCache = apiGenExecuteService.selectApiGenExecuteByApiId(apiId);
        String action = apiGenExecuteCache.getAction();

        if(parameterFromBody==null && (ApiGenConstants.CREATE.equals(action.trim().toLowerCase(Locale.ROOT))
                || ApiGenConstants.UPDATE.equals(action.trim().toLowerCase(Locale.ROOT)))
        ){
            log.info("操作类型是CREATE、UPDATE不可以没有入参");
            return badrequest("参数列表错误（缺少）");
        }

        // 2.4 获取请求出入参
        ApiGenAccess apiGenAccessCache = apiGenAccessService.selectApiGenAccessByApiId(apiId);

        // 3.拼接sql执行
        switch (action.trim().toLowerCase(Locale.ROOT)){
            case ApiGenConstants.CREATE:
                return iApiGenService.createImpl(parameterFromBody,apiGenInfoCache,apiGenAccessCache,apiGenExecuteCache);
            case ApiGenConstants.UPDATE:
                return iApiGenService.updateImpl(parameterFromBody,apiGenInfoCache,apiGenAccessCache,apiGenExecuteCache);
            case ApiGenConstants.SELECT:
                return iApiGenService.selectImpl(parameterFromBody,apiGenInfoCache,apiGenAccessCache,apiGenExecuteCache);
            case ApiGenConstants.EXPORT:
                return iApiGenService.exportImpl(parameterFromBody,apiGenInfoCache,apiGenAccessCache,apiGenExecuteCache,response);
            default:
                return warn("不支持的操作类型");
        }
        // 4.按出参格式和要求返回数据
    }

    /**
     * 获取请求body入参
     * @param request
     * @throws IOException
     */
    private JSONObject getParameterFromBody(HttpServletRequest request) throws Exception {
        InputStream inputStream = request.getInputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        while ((line = reader.readLine()) != null) {
            stringBuilder.append(line);
        }
        log.info("请求参数:{}",stringBuilder);
        if(stringBuilder.length() == 0){
            return null;
        }
        JSONObject jsonObject = JSONUtil.parseObj(stringBuilder);
        log.info("请求参json数格式化:{}",jsonObject.toString());
        return jsonObject;
    }
}
